﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using TimHeuer.WindowsLiveWriter.S34Writer.S3Model;
using Affirma.ThreeSharp.Model;

namespace TimHeuer.WindowsLiveWriter.S34Writer
{
    public partial class FileUploadProgress : Form
    {
        private const string PROGRESS_FORMAT_STRING = "{0}% complete";
        private FileUploadData _data;
        private ObjectAddRequest _addRequest = null;
        private bool _cancelled = false;

        public FileUploadProgress()
        {
            InitializeComponent();
        }

        internal void SetUploadInfo(ThreeSharpWrapper s3Wrapper, S3Bucket bucket, string key, string localFile, string contentType)
        {
            _data = new FileUploadData(s3Wrapper, bucket, key, localFile, contentType);
        }

        protected override void OnLoad(EventArgs e)
        {
            BeginUpload();
            base.OnLoad(e);
        }

        private void BeginUpload()
        {
            backgroundWorker.RunWorkerAsync(_data);
            progressBackgroundWorker.RunWorkerAsync();
        }

        private void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            FileUploadData data = e.Argument as FileUploadData;
            if (data != null)
            {
                _addRequest = data.Wrapper.StartAddFileObject(data.Bucket.Name, data.Key, data.LocalFile, data.ContentType);
                data.Wrapper.EndAddFileObject(_addRequest);
            }
        }

        private void backgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            // Success
            if (e.Error == null)
            {
                DialogResult = DialogResult.OK;
            }
            else if (_cancelled)
            {
                // The operation was cancelled by the user
                DialogResult = DialogResult.Cancel;
            }
            else
            {
                OnError();
            }
        }

        private void OnError()
        {
            MessagePanel.Visible = true;
            ProgressPanel.Visible = false;
        }

        private void CancelButton_Click(object sender, EventArgs e)
        {
            _cancelled = true;
            progressBackgroundWorker.CancelAsync();
        }

        #region Progress Background Worker

        private void progressBackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
        {
            bool cancelled = false;

            // As long as backgroundWorker is running, report the progress
            while (backgroundWorker.IsBusy)
            {
                if (_addRequest != null)
                {
                    int progress = (int)(((double)_addRequest.BytesTransferred / (double)_addRequest.BytesTotal) * 100);
                    progressBackgroundWorker.ReportProgress(progress);

                    if (progressBackgroundWorker.CancellationPending && !cancelled)
                    {
                        // "Cancel" this request - close the request stream
                        _addRequest.DataStream.Close();
                        cancelled = true;
                    }
                }

                // Wait for 100ms
                System.Threading.Thread.Sleep(100);
            }
        }

        private void progressBackgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            ProgressBar.Value = e.ProgressPercentage;
            ProgressLabel.Text = String.Format(PROGRESS_FORMAT_STRING, e.ProgressPercentage);
        }

        private void progressBackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {

        }

        #endregion Progress Background Worker

        private class FileUploadData
        {
            public ThreeSharpWrapper Wrapper;
            public S3Bucket Bucket;
            public string Key;
            public string LocalFile;
            public string ContentType;

            public FileUploadData(ThreeSharpWrapper wrapper, S3Bucket bucket, string key, string localFile, string contentType)
            {
                Wrapper = wrapper;
                Bucket = bucket;
                Key = key;
                LocalFile = localFile;
                ContentType = contentType;
            }
        }
    }
}
